home *** CD-ROM | disk | FTP | other *** search
/ Shareware Overload Trio 2 / Shareware Overload Trio Volume 2 (Chestnut CD-ROM).ISO / dir34 / pbformt2.zip / PBFORMAT.BAS
BASIC Source File  |  1993-10-14  |  15KB  |  443 lines

  1. 'PBFORMAT.BAS by Thaddy de Koning, based on:
  2. 'QBFORMAT.BAS by Cornel Huth.
  3. '14-October-1993 - Modified to format 2.8MB Floppies by Allen Hillman
  4. 'format MS-DOS floppy disks using PB and BIOS
  5. %F360 = &HFD
  6. %F1200 = &HF9
  7. 'NOTE: Original code contained mayor BUG with 3.5 inch types
  8. 'Fixed that in this PB version.
  9. '*** %F720 media byte is NEGATIVE to differ from %F1200 ***
  10. %F720 = -&HF9
  11. %F1440 = &HF0
  12. '*** %F2880 media byte is negative to differ from %F1440
  13. %F2880 = -&HF0
  14. %RETRIES = 5                            '%RETRIES on BIOS error
  15. $INCLUDE "c:\pb3\REGNAMES.INC"
  16. TYPE ADDRFIELDtype
  17.   track AS STRING * 1
  18.   head AS STRING * 1
  19.   sector AS STRING * 1
  20.   bytesec AS STRING * 1
  21. END TYPE '4
  22. TYPE INFOtype
  23.   OEM AS STRING * 8                     'system name
  24.   BS AS WORD                            'bytes/sector
  25.   SC AS BYTE                            'STRING * 1 'sectors/cluster
  26.   RS AS WORD                            'reserved sectors
  27.   NF AS BYTE                            'STRING * 1 'FATs
  28.   DE AS WORD                            'root directory entries
  29.   TS AS WORD                            'total sectors on volume
  30.   MB AS STRING * 1                      'media byte
  31.   SF AS WORD                            'sectors/FAT
  32.   ST AS WORD                            'sectors/track
  33.   NH AS WORD                            'heads
  34.   HS AS WORD                            'hidden sectors
  35. END TYPE '27
  36. TYPE BOOTRECtype
  37.   jmp AS STRING * 3
  38.   parms AS INFOtype
  39.   code AS STRING * 482
  40. END TYPE '512
  41. DEFINT A-Z
  42. 'INT 1Eh disk parameter table vectors
  43. DIM OldDPTseg AS SHARED WORD, OldDPToff AS SHARED WORD
  44. DIM NewDPTseg AS SHARED WORD, NewDPToff AS SHARED WORD
  45. 'Number of tracks on media
  46. SHARED NoTracks
  47. 'format info for media
  48. DIM Info AS SHARED INFOtype
  49. 'interface with INTERRUPTX routine
  50. 'boot record buffer
  51. DIM BootRec AS SHARED BOOTRECtype
  52. 'sector buffer to write FAT & root directory sectors
  53. DIM SectorBuff AS SHARED STRING * 512
  54. $STATIC
  55. 'Allocate address field data to max possible sectors per track
  56. DIM AddrField(1 TO 36) AS SHARED ADDRFIELDtype
  57. BootSector:
  58. DATA &HEB,&H3E,&H90,&H20,&H20,&H20,&H20,&H20,&H20,&H20,&H20,&H0,&H0,&H0,&H0,&H0
  59. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  60. DATA &HA,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  61. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  62. DATA &H2B,&HC0,&H8E,&HD0,&HBC,&H0,&H7C,&HB8,&HC0,&H7,&H8E,&HD8,&H8E,&HC0,&HBE,&H3
  63. DATA &H0,&HBF,&HAF,&H0,&HB9,&H4,&H0,&HF3,&HA5,&HBE,&HAF,&H0,&HB4,&HE,&H8A,&H4
  64. DATA &HA,&HC0,&H74,&H7,&H56,&HCD,&H10,&H5E,&H46,&HEB,&HF1,&HFC,&HBE,&H7A,&H0,&HBF
  65. DATA &H0,&H2,&HB9,&H0,&H2,&HF3,&HA4,&HE9,&H86,&H1,&HB8,&H1,&H2,&H2B,&HDB,&HB9
  66. DATA &H1,&H0,&HBA,&H50,&H0,&HCD,&H13,&H72,&HC,&HBB,&HFE,&H1,&H81,&H3F,&H55,&HAA
  67. DATA &H75,&H3,&HE9,&HE5,&HFD,&HBE,&H58,&H2,&HB4,&HE,&H8A,&H4,&HA,&HC0,&H74,&H7
  68. DATA &H56,&HCD,&H10,&H5E,&H46,&HEB,&HF1,&H2B,&HC0,&HCD,&H16,&HCD,&H19,&HCD,&H18,&H20
  69. DATA &H20,&H20,&H20,&H20,&H20,&H20,&H20,&H20,&H6E,&H6F,&H6E,&H2D,&H62,&H6F,&H6F,&H74
  70. DATA &H61,&H62,&H6C,&H65,&H20,&H64,&H69,&H73,&H6B,&H20,&H69,&H6E,&H20,&H41,&H3A,&HD
  71. DATA &HA,&H0,&H4E,&H6F,&H20,&H62,&H6F,&H6F,&H74,&H20,&H64,&H69,&H73,&H6B,&H20,&H66
  72. DATA &H6F,&H75,&H6E,&H64,&H2C,&H20,&H72,&H65,&H70,&H6C,&H61,&H63,&H65,&H20,&H61,&H6E
  73. DATA &H64,&H20,&H70,&H72,&H65,&H73,&H73,&H20,&H61,&H20,&H6B,&H65,&H79,&H20,&HD,&HA
  74. DATA &HD,&HA,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  75. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  76. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  77. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  78. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  79. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  80. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  81. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  82. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  83. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  84. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  85. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  86. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  87. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  88. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0
  89. DATA &H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H0,&H55,&HAA
  90. '============================================================================
  91. 'The following code is a sample run to format a disk
  92. 'All other code can be compiled and put in a library
  93. 'format test drive A: double-sided/36-sector media (2880K)
  94. drive = 0: media = %F1440
  95. CLS : DO: LOOP WHILE INKEY$ <> ""
  96. INPUT "Insert disk to format in drive A: and press a key", a$
  97. INPUT "Press a key to start PBFORMAT", a$
  98. PRINT
  99.  
  100. xerr = PBFORMAT(drive, media)
  101. IF xerr THEN
  102.   errl = xerr \ 256
  103.   errc = xerr AND 255
  104.   PRINT "*** Error level:"; errl; " code:"; errc
  105. ELSE
  106.   PRINT "done."
  107. END IF
  108. STOP
  109.  
  110. SUB ComputeCHS (LogSec, cyl, hd, sec)
  111. 'convert a DOS logical sector to BIOS form
  112. CylSec = Info.ST * Info.NH
  113. cyl = LogSec \ CylSec
  114. rm = LogSec - (cyl * CylSec)
  115. hd = rm \ Info.ST
  116. sec = rm - (hd * Info.ST) + 1
  117. END SUB
  118. FUNCTION FormatDisk (drive)
  119. 'format a track at a time a side at a time
  120. 'any error aborts format,diskette presumed unreliable
  121. 'retry format 1 or 2 more times before trashing the diskette
  122. y=Pos(0)
  123. x=CSRLIN
  124. FOR track = 0 TO (NoTracks - 1)
  125.   LOCATE x,y:PRINT "Formatting track:";track
  126.   'This is where you insert any printed info.
  127.   'If you don't want it, remove it......
  128.   FOR head = 0 TO (Info.NH - 1)
  129.     FOR i = 1 TO %RETRIES
  130.       xerr = FormatTrack(drive, track, head)
  131.       IF xerr = 0 THEN EXIT FOR
  132.     NEXT
  133.     IF xerr THEN FormatDisk = xerr: EXIT FUNCTION
  134.   NEXT
  135. NEXT
  136. FormatDisk = 0
  137. END FUNCTION
  138. FUNCTION FormatTrack (drive, track, head)
  139. 'Initialize address field for each sector on this track
  140. FOR sec = 1 TO Info.ST
  141.   AddrField(sec).track = CHR$(track)
  142.   AddrField(sec).head = CHR$(head)
  143.   AddrField(sec).sector = CHR$(sec)
  144.   AddrField(sec).bytesec = CHR$(2)      'bytecode 2 = 512-byte sector
  145. NEXT
  146. reg %ax, &H500 + Info.ST                'format track with sectors/track
  147. reg %cx, (track * 256) + 1              'track to format,start with sector 1
  148. Reg %dx, (head * 256) + drive           'head,drive
  149. Reg %es, VARSEG(AddrField(1))           'point to address field data
  150. Reg %bx, VARPTR(AddrField(1))
  151. CALL INTERRUPT &H13
  152. cf = Reg (%flags) AND 1                 'cf=1 if disk error
  153. IF cf THEN
  154.   E?? = Reg (%ax)
  155.   'IF e& < 0 THEN e& = e& + 65536
  156.   SHIFT RIGHT e??,8                     ' = e& \ 256 'return with status byte
  157.   Formattrack=e??
  158.   ResetFDC drive
  159. ELSE
  160.   Reg %ax, &H400 + Info.ST              'ok, verify track integrity-
  161.   CALL INTERRUPT &H13                   '-optional but recommended on format
  162.   cf = Reg (%flags) AND 1               'cf=1 if disk error
  163.   IF cf THEN
  164.     e?? = Reg (%ax)
  165.     SHIFT RIGHT e??,8                   ' = e?? \ 256 'return with status byte
  166.     Formattrack=e??
  167.     ResetFDC drive
  168.   ELSE
  169.     FormatTrack = 0                     'format ok
  170.   END IF
  171. END IF
  172. END FUNCTION
  173. SUB InitFormatParms (media)
  174. 'set up media's format data
  175. Info.OEM = "IBM  PB3"                   'avoid changing 'IBM'
  176. Info.BS = 512
  177. Info.RS = 1
  178. Info.NF = 2                             'CHR$(2)
  179. Info.NH = 2
  180. Info.HS = 0
  181. SELECT CASE media
  182. CASE %F360
  183.   Info.SC = 2                           'CHR$(2)
  184.   Info.DE = 112
  185.   Info.TS = 720
  186.   Info.MB = CHR$(%F360)
  187.   Info.SF = 2
  188.   Info.ST = 9
  189. CASE %F1200
  190.   Info.SC = 1                           'CHR$(1)
  191.   Info.DE = 224
  192.   Info.TS = 2400
  193.   Info.MB = CHR$(%F1200)
  194.   Info.SF = 7
  195.   Info.ST = 15
  196. CASE %F720
  197.   Info.SC = 2                           'CHR$(2)
  198.   Info.DE = 112
  199.   Info.TS = 1440
  200.   Info.MB = CHR$(ABS(%F720))
  201.   Info.SF = 3
  202.   Info.ST = 9
  203. CASE %F1440
  204.   Info.SC = 1                           'CHR$(1)
  205.   Info.DE = 224
  206.   Info.TS = 2880
  207.   Info.MB = CHR$(%F1440)
  208.   Info.SF = 9
  209.   Info.ST = 18
  210. case %F2880
  211.   Info.SC = 2                           'CHR$(2)
  212.   Info.DE = 240
  213.   Info.TS = 5760
  214.   Info.MB = CHR$(ABS(%F2880))
  215.   Info.SF = 9
  216.   Info.ST = 36
  217. CASE ELSE
  218.   Info.OEM = ""
  219.   Info.BS = 0
  220.   Info.RS = 0
  221.   Info.NF = 0                           'CHR$(0)
  222.   Info.NH = 0
  223.   Info.HS = 0
  224.   Info.SC = 0                           'CHR$(0)
  225.   Info.DE = 0
  226.   Info.TS = 0
  227.   Info.MB = CHR$(0)
  228.   Info.SF = 0
  229.   Info.ST = 0
  230. END SELECT
  231. NoTracks = Info.TS \ Info.NH \ Info.ST
  232. NewDPTseg = 0                           'INT 1Eh vector
  233. NewDPToff = 0                           'new -> disk parameter table for formatted media
  234. OldDPTseg = 0                           'original-
  235. OldDPToff = 0                           '-vector
  236. END SUB
  237. FUNCTION PBFORMAT (drive, media)
  238. 'control routine
  239. xerr = ValidateDisk(drive, media)
  240. IF xerr = 0 THEN xerr = FormatDisk(drive) ELSE level = 1
  241. IF xerr = 0 THEN xerr = WriteBoot(drive) ELSE IF level = 0 THEN level = 2
  242. IF xerr = 0 THEN xerr = WriteFAT(drive) ELSE IF level = 0 THEN level = 3
  243. IF xerr = 0 THEN xerr = WriteDir(drive) ELSE IF level = 0 THEN level = 4
  244. IF xerr THEN IF level = 0 THEN level = 5
  245. 'reset INT 1Eh vector to original,check both for <>0
  246. IF OldDPTseg <> 0 OR OldDPToff <> 0 THEN
  247.   Reg %ax, &H251E
  248.   Reg %ds, OldDPTseg
  249.   Reg %dx, OldDPToff
  250.   CALL INTERRUPT &H21
  251. END IF
  252. PBFORMAT = (level * 256) + xerr
  253. 'sample call
  254. 'xerr = PBFORMAT(drive, media)
  255. 'IF xerr THEN errl = xerr \ 256: errc = xerr AND 255
  256. 'level error codes
  257. '0:no error
  258. '1:validate error
  259. '2:format error
  260. '3:boot record write error
  261. '4:FAT write error
  262. '5:directory write error
  263. 'floppy disk error codes (xerr,in decimal):
  264. '0:no error
  265. '1:invalid function request
  266. '2:address mark not found
  267. '3:write protected
  268. '4:sector not found
  269. '6:diskette changed
  270. '8:DMA overrun
  271. '9:DMA boundary error
  272. '12:media type not available
  273. '16:bad CRC
  274. '32:diskette controller failed
  275. '64:seek failed
  276. '128:time-out/drive not ready
  277. END FUNCTION
  278. SUB ResetFDC (drive)
  279. 'reset the controller after any BIOS FDC error
  280. Reg %ax, 0
  281. Reg %dx, drive
  282. CALL INTERRUPT &H13
  283. END SUB
  284. FUNCTION ValidateDisk (drive, media)
  285. 'check if media supported by program,by drive,and if drive is ready
  286. InitFormatParms media
  287. IF Info.ST THEN
  288.   'check to see if there is CMOS RAM (means we have an AT BIOS)
  289.   OUT &H70, &H10
  290.   CMOS = (INP(&H71) <> &HFF)
  291.   ResetFDC drive
  292.   IF CMOS THEN
  293.     'get original INT 1Eh vector to disk parameter table
  294.     Reg %ax, &H351E
  295.     CALL INTERRUPT &H21
  296.     OldDPTseg = Reg (%es)
  297.     OldDPToff = Reg (%bx)
  298.     'set media type for format on AT BIOS/multi-media drive
  299.     'let BIOS determine if drive can format media with a DPT in BIOS ROM
  300.     'Reg %ax, &H1800
  301.     'Reg %cx, ((NoTracks - 1) * 256) + Info.ST
  302.     'Reg %dx, drive
  303.     FOR checks = 1 TO %RETRIES          'zerr=0 no error
  304.       Reg %ax, &H1800
  305.       Reg %cx, ((NoTracks - 1) * 256) + Info.ST
  306.       Reg %dx, drive
  307.       CALL INTERRUPT &H13
  308.       zerr = Reg (%ax) \ 256            'zerr=&H0C unknown media/maybe invalid CMOS
  309.       IF zerr THEN ResetFDC drive ELSE EXIT FOR
  310.     NEXT
  311.     'set INT 1Eh vector to this media's disk parameter table in BIOS ROM
  312.     IF zerr = 0 THEN
  313.       NewDPTseg = Reg (%es)
  314.       NewDPToff = Reg (%di)
  315.       Reg %ax, &H251E
  316.       Reg %ds, NewDPTseg
  317.       Reg %dx, NewDPToff
  318.       CALL INTERRUPT &H21
  319.     ELSE
  320.       OldDPTseg = 0
  321.       OldDPToff = 0
  322.     END IF
  323.   END IF
  324. ELSE
  325.   zerr = &HC                            'media not supported by program
  326. END IF
  327. 'physical check for disk in the drive
  328. IF zerr = 0 THEN
  329.   Reg %ax, &H401                        'verify 1 sector from drive
  330.   Reg %cx, &H1                          'track=0 sector=1
  331.   Reg %dx, drive                        'head=0 drive=drive
  332.   FOR checks = 1 TO %RETRIES
  333.     CALL INTERRUPT &H13
  334.     IF Reg ((%flags) AND 1) THEN        'bad read
  335.       zerr = Reg (%ax)
  336.       'need to detect an unformatted disk
  337.       shift right zerr,8                ' = e?? \ 256
  338.       ResetFDC drive
  339.     ELSE
  340.       zerr = 0                          'good read,already formatted disk in drive
  341.       EXIT FOR
  342.     END IF
  343.   NEXT
  344.   'zerr may be any of the BIOS diskette error codes if non-zero here
  345.   'address mark not found(2)=unformatted disk in drive
  346.   'sector not found(4)=wacko disk but okay to proceed
  347.   IF zerr = 2 OR zerr = 4 THEN zerr = 0
  348. END IF
  349. ValidateDisk = zerr
  350. END FUNCTION
  351.  
  352. FUNCTION WriteBoot (drive)
  353. RESTORE BootSector
  354. 'read default boot record data
  355. DEF SEG = VARSEG(BootRec): offset = VARPTR(BootRec)
  356. FOR i = 0 TO 511: READ byte: POKE offset + i, byte: NEXT: DEF SEG
  357. 'update OEM name and BIOS parameter block
  358. BootRec.parms = Info
  359. 'write the boot record
  360. FOR i = 1 TO %RETRIES
  361.   xerr = WriteBootSector(drive)
  362.   IF xerr = 0 THEN EXIT FOR
  363. NEXT
  364. WriteBoot = xerr
  365. END FUNCTION
  366.  
  367. FUNCTION WriteBootSector (drive)
  368. Reg %ax, &H300 + 1                      'write 1 sector
  369. Reg %cx, 1                              'track 0,sector 1
  370. Reg %dx, drive                          'head 0,drive
  371. Reg %es, VARSEG(BootRec)                'point to boot record data
  372. Reg %bx, VARPTR(BootRec)
  373. CALL INTERRUPT &H13
  374. cf = Reg (%flags) AND 1                 'cf=1 if disk error
  375. IF cf THEN
  376.   e?? = Reg (%ax)
  377.   WriteBootSector = e?? \ 256           'return with status byte
  378.   ResetFDC drive
  379. ELSE
  380.   WriteBootSector = 0                   'ok
  381. END IF
  382. END FUNCTION
  383. FUNCTION WriteDir (drive)
  384. MID$(SectorBuff, 1, 1) = CHR$(0)
  385. FOR i = 2 TO 512
  386.   IF (i - 1) MOD 32 = 0 THEN
  387.     MID$(SectorBuff, i, 1) = CHR$(0)
  388.   ELSE
  389.     MID$(SectorBuff, i, 1) = CHR$(&HF6)
  390.   END IF
  391. NEXT
  392. LogSec = Info.RS + Info.HS + (Info.SF * Info.NF) 'first logical dir sector
  393. FOR i = 1 TO (Info.DE \ 16)             'sectors needed for root directory
  394.   ComputeCHS LogSec, cyl, hd, sec
  395.   FOR k = 1 TO %RETRIES
  396.     xerr = WriteSector(drive, cyl, hd, sec)
  397.     IF xerr = 0 THEN EXIT FOR
  398.   NEXT
  399.   IF xerr THEN WriteDir = xerr: EXIT FUNCTION
  400.   LogSec = LogSec + 1
  401. NEXT
  402. WriteDir = 0
  403. END FUNCTION
  404.  
  405. FUNCTION WriteFAT (drive)
  406. ' do the hussle
  407. FAT1$ = Info.MB + CHR$(255) + CHR$(255)
  408. FAT2$ = CHR$(0) + CHR$(0) + CHR$(0)
  409. FOR i = 1 TO 512: MID$(SectorBuff, i, 1) = CHR$(0): NEXT
  410. LogSec = Info.RS + Info.HS                'first logical FAT sector
  411. FOR i = 1 TO Info.NF
  412.   FOR j = 1 TO Info.SF
  413.     IF j = 1 THEN MID$(SectorBuff, 1) = FAT1$ ELSE MID$(SectorBuff, 1) = FAT2$
  414.     ComputeCHS LogSec, cyl, hd, sec
  415.     FOR k = 1 TO %RETRIES
  416.       xerr = WriteSector(drive, cyl, hd, sec)
  417.       IF xerr = 0 THEN EXIT FOR
  418.     NEXT
  419.     IF xerr THEN WriteFAT = xerr: EXIT FUNCTION
  420.     LogSec = LogSec + 1
  421.   NEXT
  422. NEXT
  423. WriteFAT = 0
  424. END FUNCTION
  425.  
  426. FUNCTION WriteSector (drive, cyl, hd, sec)
  427. 'BIOS write a FAT or directory sector
  428. Reg %ax, &H300 + 1
  429. Reg %cx, (cyl * 256) + sec
  430. Reg %dx, (hd * 256) + drive
  431. Reg %es, VARSEG(SectorBuff)
  432. Reg %bx, VARPTR(SectorBuff)
  433. CALL INTERRUPT &H13
  434. cf = Reg (%flags) AND 1
  435. IF cf THEN
  436.   e?? = Reg (%ax)
  437.   WriteSector = e?? \ 256
  438.   ResetFDC drive
  439. ELSE
  440.   WriteSector = 0
  441. END IF
  442. END FUNCTION
  443.